<?php

namespace App\Services\FaceRecognition\Drivers;

use App\Services\FaceRecognition\FaceRecognitionResult;
use App\Services\FaceRecognition\FaceRecognitionVerifier;
use com\junziqian\sdk\util\RequestUtils;
use Illuminate\Support\Facades\Log;
use RuntimeException;
use Throwable;

class JunziqianFaceRecognitionVerifier implements FaceRecognitionVerifier
{
    protected array $config;

    public function __construct(array $config)
    {
        $this->config = $config;
    }

    public function start(array $params): FaceRecognitionResult
    {
        $this->ensureConfigured();

        $requestPayload = $this->buildPayload($params);

        Log::info('[FaceRecognition][Junziqian] 请求参数', [
            'endpoint' => $this->config['service_url'] ?? null,
            'payload' => $requestPayload,
        ]);

        try {
            $client = $this->createClient();
            $path = $this->config['path'] ?? '/v2/auth/startH5Face';
            $response = $client->doPost($path, $requestPayload);
        } catch (Throwable $e) {
            Log::error('[FaceRecognition][Junziqian] 请求异常', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            return FaceRecognitionResult::failure('人脸核验供应商请求异常', null, [
                'payload' => $requestPayload,
                'exception' => [
                    'message' => $e->getMessage(),
                    'file' => $e->getFile(),
                    'line' => $e->getLine(),
                ],
            ]);
        }

        $responseArray = $this->normalizeResponse($response);

        Log::info('[FaceRecognition][Junziqian] 返回结果', [
            'response' => $responseArray,
        ]);

        $success = (bool) ($responseArray['success'] ?? false);
        $data = $responseArray['data'] ?? [];
        $resultMessage = (string) ($responseArray['msg'] ?? '');
        $resultCode = (string) ($responseArray['code'] ?? '');

        if ($success) {
            return FaceRecognitionResult::success([
                'orderNo' => $params['orderNo'],
                'startFaceUrl' => $data['startFaceUrl'],
            ], $resultMessage ?: '人脸核验链接获取成功', [
                'response' => $responseArray,
            ]);
        }

        return FaceRecognitionResult::failure($resultMessage ?: '人脸核验失败', $resultCode ?: null, [
            'response' => $responseArray,
        ]);
    }

    protected function ensureConfigured(): void
    {
        foreach (['service_url', 'app_key', 'app_secret'] as $key) {
            if (empty($this->config[$key])) {
                throw new RuntimeException(sprintf('人脸识别 Junziqian 驱动缺少配置项 [%s]', $key));
            }
        }
    }

    protected function buildPayload(array $params): array
    {
        $payload = [
            'orderNo' => $params['orderNo'] ?? uniqid('FACE_'),
            'name' => $params['name'] ?? '',
            'identityCard' => $params['identityCard'] ?? '',
        ];

        if (! empty($params['backUrl'])) {
            $payload['backUrl'] = $params['backUrl'];
        }

        if (! empty($params['startFrom'])) {
            $payload['startFrom'] = $params['startFrom'];
        }

        if (! empty($params['notifyUrl'])) {
            $payload['notifyUrl'] = $params['notifyUrl'];
        }

        return $payload;
    }

    protected function createClient(): RequestUtils
    {
        $serviceUrl = rtrim($this->config['service_url'], '/');
        $appKey = $this->config['app_key'];
        $appSecret = $this->config['app_secret'];
        $encryMethod = $this->config['encry_method'] ?? null;
        $tsType = $this->config['ts_type'] ?? 2;

        return new RequestUtils($serviceUrl, $appKey, $appSecret, $encryMethod, $tsType);
    }

    protected function normalizeResponse($response): array
    {
        if (is_array($response)) {
            return $response;
        }

        if (is_object($response)) {
            return json_decode(json_encode($response), true) ?: [];
        }

        return [];
    }
}
